

#ifndef __CE_SKELETON_H__
#define __CE_SKELETON_H__

#include <cegfx/ceexport.h>
#include <cegfx/igeometryanimator.h>
#include <cecore/iqf.h>
#include <d3dx9.h>

#include <vector>

class ceBone;
class CE_GFX_API ceBone : public virtual iBase
{
	friend class ceSkeleton;
private:
	IQF_DECLARATION;

	D3DXMATRIX						*matrix;

	float									length;

	D3DXQUATERNION				quaternion;

	ceBone*								parent;

	std::vector<ceBone*>	children;

	std::string						name;

	unsigned							id;

private:
	ceBone (const char* name);

	void SetMatrix (D3DXMATRIX* matrix);
	void SetId (unsigned id);

public:
	unsigned GetId () const;
	const char* GetName () const;

	void SetLength (float length);
	float GetLength () const;

	void SetRotation (const D3DXVECTOR3& axis, float angle);
	const D3DXQUATERNION& GetQuaternion () const;

	void AddBone (ceBone* bone);
	void RemoveBone (const ceBone* bone);

	void Update (const D3DXMATRIX& base);

	void Debug ();

};

class CE_GFX_API ceSkeleton : public virtual iGeometryAnimator
{
	IQF_DECLARATION;
private:
	std::vector<ceBone*>		bones;

	std::vector<ceBone*>		rootBones;

	D3DXMATRIX*							matrices;

public:
	ceSkeleton ();


	ceBone* CreateBone (const char* name, float length, bool rootBone = true);
	ceBone* CreateBone (const char* name, float length, ceBone* parent);

	void Build ();

	void Update ();
	void Update (const D3DXMATRIX& base);
	void Debug ();

	unsigned GetNumberOfBones () const;
	const ceBone* GetBone (unsigned i) const;
	ceBone* GetBone (unsigned i);

	const ceBone* GetBone (const char* name) const;
	ceBone* GetBone (const char* name);

	const D3DXMATRIX* GetBoneMatrices () const;
	
	virtual void UpdateGeometry (iGeometry* geometry);
	virtual void UpdateEffectStates (ceEffect* effect);

};


#endif /* __CE_SKELETON_H__ */ 
